``




const { Question, Examination, ExamPaper, ExamQuestion, TestPaper, TestQuestion, User, Organization, AnswerPaper, AnswerQuestion, sequelize, Op } = require('../model/dbModel/index')
const { isAnswerQuestionArray } = require('../model/appModel/json_schema/vaildata/answerQuestionsVaildata')


/**
 * 添加考试
 * @param {string} name 考试名
 * @param {string} exam_description 考试介绍
 * @param {Date} exam_open_time 考试开始时间
 * @param {Date} exam_close_time 考试结束时间
 * @param {Date} limit_time 考试限时
 * @param {Number} org_id 组织ID
 * @param {Number} tp_id 试卷ID
 * @param {String} username 用户名
 * @return {Promise<{msg: string, status: number}>}
 */
async function addExam(name, exam_description, exam_open_time, exam_close_time, limit_time, org_id, tp_id, username) {
    //基础属性校验
    {
        if (!name) return { status: 23, msg: "考试名称不能为空" }
        if (!exam_open_time) return { status: 23, msg: "考试开始时间不能为空" }
        if (exam_open_time > 253402271999999) return { status: 23, msg: "考试开始时间过大" }
        if (exam_close_time > 253402271999999) return { status: 23, msg: "考试结束时间过大" }
        if (limit_time > 253402271999999) return { status: 23, msg: "考试限时过长" }
        if (exam_open_time < new Date()) return { status: 23, msg: "考试开始时间不能早于当前时间" }
        if (!exam_close_time) return { status: 23, msg: "考试开始时间不能为空" }
        if (exam_close_time <= exam_open_time) return { status: 23, msg: "考试结束时间不能早于考试开始时间" }
        if (!limit_time) {
            limit_time = exam_close_time - exam_open_time;
        } else if (limit_time > (exam_close_time - exam_open_time)) {
            return {
                status: 23,
                msg: "考试限制时长不得超过考试开始时间与考试结束时间之差"
            }
        } else if (limit_time < 0) {
            return { status: 23, msg: "考试限制时长不能小于0秒" }
        }
        if (!username) return { status: 23, msg: "用户名不能为空" }
        if (!org_id) return { status: 23, msg: "组织号不能为空" }
        if (!tp_id) return { status: 23, msg: "试卷号不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断用户的权限
    if (user.userrole !== "teacher") return {
            status: 12,
            msg: "该用户不是教师暂无权限创建考试"
        }
        //判断组织的所有者是否是该用户
    let org = await Organization.findOne({
        where: {
            id: org_id,
            creator_id: user.id
        }
    })
    if (!org) return {
            status: 12,
            msg: "用户没有该组织创建考试的权限或该组织不存在"
        }
        //判断试卷是否存在或者用户是否有权限使用试卷
    let tp = await TestPaper.findOne({
        where: {
            id: tp_id,
            creator_id: user.id
        }
    })
    if (!tp) return { status: 12, msg: "该用户没有试卷的操作权限或试卷不存在" }

    //新建考试
    let exam = await Examination.create({
            exam_name: name,
            exam_description: exam_description,
            exam_open_time: exam_open_time,
            exam_close_time: exam_close_time,
            limit_time: limit_time,
            org_id: org.id,
        })
        .catch(e => {
            return e
        })
        //新建考卷
    let ep = await ExamPaper.create({
        exam_paper_name: tp.tp_name,
        exam_paper_description: tp.tp_description
    })
    let updateNum = await Examination.update({
        exam_paper_id: ep.id
    }, {
        where: {
            id: exam.id
        }

    })

    //添加考题
    let result = await saveExamQuestionFromTestPaper(tp_id, ep.id).catch(e => console.log(e))
    return {
        status: 0,
        msg: "新建考试成功"
    }
}

/**
 * 获取考试列表
 * @param {Number} page 页码
 * @param {Number} pageSize 页面大小
 * @param {String} username 用户名
 * @return {Promise<{msg: string, status: number}>}
 */
async function examList(page, pageSize, username) {
    //判断用户合法性
    //
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
        status: 11,
        msg: "用户不存在"
    }
    let examList = await Examination.findAll({
        include: {
            model: Organization,
            where: {
                creator_id: user.id
            },
        },
        attributes: {
            include: [
                [sequelize.literal("(SELECT username FROM users as u1 where u1.id = Organization.creator_id )"), 'creator_username'],
                [sequelize.literal("(SELECT usernickname FROM users as u1 where u1.id = Organization.creator_id )"), 'creator_nickname'],
                [sequelize.literal("(SELECT id FROM users as u1 where u1.id = Organization.creator_id )"), 'creator_id'],
            ],
        },

    }).catch(e => console.log(e))
    return {
        data: examList,
        status: 0,
        msg: "查询考试列表成功"
    }
}

/**
 * 获取考试详情列表
 * @param {Number} exam_id 考试id
 * @param {String} username 用户名
 * @return {Promise<{msg: string, status: number}>}
 */
async function examDetail(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断考试是否存在
    let exam = await Examination.findOne({
        where: {
            id: exam_id
        }
    })
    if (!exam) return {
            status: 51,
            msg: "考试不存在"
        }
        //判断用户是否可以查看考试详情（用户是否是这场考试所属组织的创建者）
    let org = await Organization.findOne({
        where: {
            id: exam.org_id,
        }
    })
    if (!org) return {
        status: 50,
        msg: "服务器发生了不知名的错误"
    }
    if (org.creator_id !== user.id) return {
            status: 12,
            msg: "该用户没有权限查看该考试详情"
        }
        //查询考试详情
    let ExamPaper = await getExamPaper(exam.exam_paper_id); //获取考卷（包含考题）
    let result = exam.toJSON();
    result.examPaper = ExamPaper; //把考卷置入考试
    return {
        status: 0,
        msg: "考试详情查询成功",
        data: {
            examDetail: result
        }
    }

}

/**
 * 修改考试信息
 * @param {Number} exam_id 考试id
 * @param {String} name 考试名
 * @param {String} exam_description 考试介绍
 * @param {Date} exam_open_time 考试开始时间
 * @param {Date} exam_close_time 考试结束时间
 * @param {Date} limit_time 考试限制时间
 * @param {Number} org_id 组织号
 * @param {Number} tp_id 试卷号
 * @param {String} username 用户名
 * @return {Promise<void>}
 */
async function updateExam(exam_id, name, exam_description, exam_open_time, exam_close_time, limit_time, org_id, tp_id, username) {
    //基础属性校验
    {
        if (!name) return { status: 23, msg: "考试名称不能为空" }
        if (!exam_open_time) return { status: 23, msg: "考试开始时间不能为空" }
        if (exam_open_time > 253402271999999) return { status: 23, msg: "考试开始时间过大" }
        if (exam_close_time > 253402271999999) return { status: 23, msg: "考试结束时间过大" }
        if (limit_time > 253402271999999) return { status: 23, msg: "考试限时过长" }
        if (exam_open_time < new Date()) return { status: 23, msg: "考试开始时间不能早于当前时间" }
        if (!exam_close_time) return { status: 23, msg: "考试开始时间不能为空" }
        if (exam_close_time <= exam_open_time) return { status: 23, msg: "考试结束时间不能早于考试开始时间" }
        if (!limit_time) {
            limit_time = exam_close_time - exam_open_time;
        } else if (limit_time > (exam_close_time - exam_open_time)) {
            return {
                status: 23,
                msg: "考试限制时长不得超过考试开始时间与考试结束时间之差"
            }
        } else if (limit_time < 0) {
            return { status: 23, msg: "考试限制时长不能小于0秒" }
        }
        if (!username) return { status: 23, msg: "用户名不能为空" }
        if (!org_id) return { status: 23, msg: "组织号不能为空" }
        if (!tp_id) return { status: 23, msg: "试卷号不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断用户的权限
    if (user.userrole !== "teacher") return {
            status: 12,
            msg: "该用户不是教师暂无权限创建考试"
        }
        //判断组织的所有者是否是该用户
    let org = await Organization.findOne({
        where: {
            id: org_id,
            creator_id: user.id
        }
    })
    if (!org) return {
            status: 12,
            msg: "用户没有该组织创建考试的权限或该组织不存在"
        }
        //判断试卷是否存在或者用户是否有权限使用试卷
    let tp = await TestPaper.findOne({
        where: {
            id: tp_id,
            creator_id: user.id
        }
    })
    if (!tp) return { status: 12, msg: "该用户没有试卷的操作权限或试卷不存在" }

}

/**
 * 删除考试
 * @description 已经开始的考试无法删除
 * @param exam_id
 * @param username
 * @return {Promise<void>}
 */
async function deleteExam(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断考试是否存在
    let exam = await Examination.findOne({
        where: {
            id: exam_id
        }
    })
    if (!exam) return {
            status: 51,
            msg: "考试不存在"
        }
        //判断用户是否可以查看考试详情（用户是否是这场考试所属组织的创建者）
    let org = await Organization.findOne({
        id: exam.org_id,
    })
    if (!org) return {
        status: 50,
        msg: "服务器发生了不知名的错误"
    }
    if (org.creator_id !== user.id) return {
        status: 12,
        msg: "该用户没有权限查看该考试详情"
    }

    //判断考试是否能够删除（考试已经开始则不能够删除）
    if (exam.exam_open_time < new Date()) return {
        status: 1,
        msg: "考试已经开始，无法删除考试"
    }

    //删除考试(包含：考试、考卷、考题)
    let result1 = await ExamQuestion.destroy({
            where: {
                exam_paper_id: exam.exam_paper_id
            }
        }) //删除考题
    let result2 = await ExamPaper.destroy({
            where: {
                id: exam.exam_paper_id
            }
        }) //删除考卷
    let result3 = await Examination.destroy({
            where: {
                id: exam_id
            }
        }) //删除考试

    return {
        status: 0,
        msg: "删除成功",
        examQuestionNum: result1,
        examPaperNum: result2,
        examNum: result3,
    }

}




/**
 * 我的考试列表
 * @param {Number} page 页码
 * @param {Number} pageSize 页面大小
 * @param {String} username 用户名
 * @return {Promise<void>}
 */
async function myExamList(page, pageSize, username) {
    //基础属性校验
    {
        if (!username) return { status: 23, msg: "请求参数不能为空" }
        if (!page || page < 1 || !pageSize || pageSize < 1) return {
            status: 2,
            msg: "请输入正确的页码和页面大小"
        }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //查找我所有所在的组织号
    let orgs = await Organization.findAll({
        attributes: ['id'],
        include: {
            model: User,
            where: {
                id: user.id
            },
            attributes: [],
        },
    })
    let orgIdArray = [];
    orgs.forEach(item => {
        orgIdArray.push(item.id)
    })

    //通过我所在的组织号，来查找组织内的考试
    let examList = await Examination.findAll({
        include: {
            model: Organization,
            where: {
                id: {
                    [Op.in]: orgIdArray
                },
            },
            attributes: [],
        },
        attributes: [
            'id',
            'exam_name',
            'exam_description',
            'exam_open_time',
            'exam_close_time',
            'limit_time',
            'org_id'
        ],
        order:[['exam_open_time','DESC']]
    }).catch(e => console.log(e))
    return {
        data: examList,
        status: 0,
        msg: "查询考试列表成功"
    }


}

/**
 * 开始考试，登记用户的开始答卷时间，生成该用户本场考试的答卷
 * @param exam_id
 * @param username
 * @return {Promise<{msg: string, status: number}>}
 */
async function takeExam(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }

    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断该考试是否是用户的考试
    let exam = await Examination.findOne({
        where: {
            id: exam_id
        },
        include: {
            model: Organization,
            include: {
                model: User,
                where: {
                    id: user.id
                }
            },
        }
    })
    if (!exam) return { status: 12, msg: "该用户没有该考试的权限或考试不存在" }
        //考试状态检测
        {
            //判断考试是否开始
            if (exam.exam_open_time > new Date()) return {
                    status: 1,
                    msg: "考试未开始",
                    EXAM_STATUS: 'NOT_START',
                }
                //判断考试是否结束
            if (exam.exam_close_time < new Date()) return {
                status: 1,
                msg: "考试已结束",
                EXAM_STATUS: "FINISHED",
            }
        }
        //答卷状态检测
        // # 考试正在进行中
    let ap = await AnswerPaper.findOne({
            where: {
                user_id: user.id,
                exam_paper_id: exam.exam_paper_id
            }
        }) 
        {
            //判断用户是否已经交卷
            if (ap ?.end_time) return {
                    status: 1,
                    msg: "该用户已经交卷",
                    EXAM_STATUS: "DOING",
                    ANSWERPAPER_STATUS: "SUBMITTED",
                }
                //判断用户是否已经开始答题
            if (ap && ap ?.start_time) return {
                    status: 0,
                    EXAM_STATUS: "DOING",
                    ANSWERPAPER_STATUS: 'ANSWERING',
                }
                //用户还没开始答题，可以创建答卷并开始答题
        }
        // # 用户还未答题
    if (!ap) {
        ap = await AnswerPaper.create({
            start_time: new Date(),
            user_id: user.id,
            exam_paper_id: exam.exam_paper_id,
        })
        if (ap) return {
            status: 0,
            msg: "开始考试成功",
            EXAM_STATUS: "DOING",
            ANSWERPAPER_STATUS: "ANSWERING",
        }

    }


    return {
        status: 50,
        msg: "系统出现异常"
    }

}

/**
 * 获取考试试卷
 * @description 本方法主要用在考试进行阶段的试卷获取
 * @param exam_id 考试ID
 * @param username 用户名
 * @return {Promise<void>}
 */
async function examPaper(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断考试资格
    let examStatus = await examinationStatus(exam_id, username);
    if (examStatus.status !== 0) return {
        status: examStatus.status,
        msg: examStatus.msg,
    }

    let exam = await Examination.findOne({
            where: {
                id: exam_id
            }
        }).catch(e => console.log(e))
        //判断考试状态和用户的答卷状态
    let apStatus = await answerPaperStatus(exam_id, username);
    if (examStatus.EXAM_STATUS == "DOING" ||
        apStatus.ANSWERPAPER_STATUS == "ANSWERING") {
        let ep = await getExamPaper(exam.exam_paper_id); //获取考卷
        await cutAnswerAndAnalysisOfPaper(ep); //删除考卷中的答案和解析
        let result = {
            status: 0,
            msg: "获取成功",
            data: exam.toJSON(),
        }
        result.data.examPaper = ep;
        return result;
    } else {
        return {
            status: 1,
            msg: examStatus.msg
        }
    }

}

/**
 * 保存答卷
 * @return {Promise<{msg: string, status: number}>}
 */
async function saveAnswerPaper(exam_id, aq_array, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断考试资格
    let examStatus = await examinationStatus(exam_id, username);
    if (examStatus.status !== 0) return {
        status: examStatus.status,
        msg: examStatus.msg,
    }
    if (examStatus.status === 'NOT_START') return {
        status: examStatus.status,
        msg: examStatus.msg,
    }
    let exam = await Examination.findOne({
            where: {
                id: exam_id
            }
        }).catch(e => console.log(e))
        //判断考试状态和用户的答卷状态
    let apStatus = await answerPaperStatus(exam_id, username);
    if (apStatus.ANSWERPAPER_STATUS === "ANSWERING" || apStatus.ANSWERPAPER_STATUS == "TIMEOUT") {
        let result = {
            status: -1,
            msg: "",
        }
        if (!isAnswerQuestionArray(aq_array)) {
            result.status = 21
            result.msg = "答题数组存在问题"
            return result;
        }
        //
        //获取答卷，并存入答案
        let ap = await AnswerPaper.findOne({
            where: {
                exam_paper_id: exam.exam_paper_id,
                user_id: user.id
            }
        }).catch(e => { console.log(e); return e; })
        let saveNum = 0;
        for (let i = 0; i < aq_array.length; i++) {
            let aq = await AnswerQuestion.findOne({
                where: {
                    answer_paper_id: ap.id,
                    exam_question_id: aq_array[i].eq_id
                }
            })
            if (aq) await AnswerQuestion.update({
                aq_body: aq_array[i].answer_body
            }, {
                where: {
                    answer_paper_id: ap.id,
                    exam_question_id: aq_array[i].eq_id
                }
            })
            else await AnswerQuestion.create({
                aq_body: aq_array[i].answer_body,
                answer_paper_id: ap.id,
                exam_question_id: aq_array[i].eq_id,
            });
            saveNum++;
        }
        result.status = 0
        result.msg = "保存成功"
        result.saveNum = saveNum;
        return result;

    }
    //返回异常状态
    return {
        status: 1,
        msg: apStatus.msg,
        EXAM_STATUS: examStatus ?.EXAM_STATUS,
        ANSWERPAPER_STATUS: apStatus ?.ANSWERPAPER_STATUS
    }
}

/**
 * 交卷，停止答题
 * @param exam_id
 * @param username
 * @return {Promise<void>}
 */
async function handInPaper(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
            status: 11,
            msg: "用户不存在"
        }
        //判断考试资格
    let examStatus = await examinationStatus(exam_id, username);
    if (examStatus.status !== 0) return {
        status: examStatus.status,
        msg: examStatus.msg,
    }
    if (examStatus.status === 'NOT_START') return {
        status: examStatus.status,
        msg: examStatus.msg,
    }
    let exam = await Examination.findOne({
            where: {
                id: exam_id
            }
        }).catch(e => console.log(e))
        //判断考试状态和用户的答卷状态
    let apStatus = await answerPaperStatus(exam_id, username);
    if (apStatus.ANSWERPAPER_STATUS === 'SUBMITTED') return {
        status: 1,
        msg: apStatus.msg,
        EXAM_STATUS: examStatus.EXAM_STATUS,
        ANSWERPAPER_STATUS: apStatus.ANSWERPAPER_STATUS
    }
    if (apStatus.ANSWERPAPER_STATUS === "ANSWERING" || apStatus.ANSWERPAPER_STATUS == "TIMEOUT") {
        let result = {
            status: -1,
            msg: "",
        }
        let end_time = new Date()
        let aa = await AnswerPaper.update({
            end_time: end_time
        }, {
            where: {
                exam_paper_id: exam.exam_paper_id,
                user_id: user.id
            }
        })
        result.status = 0
        result.msg = "交卷成功"
        result.data = {
            SubmitNum: aa ?? aa ?.length
        }
        return result
    }
    if (apStatus.ANSWERPAPER_STATUS === 'NOT_ANSWER') {
        return {
            status: 1,
            msg: apStatus.msg,
            EXAM_STATUS: examStatus.EXAM_STATUS,
            ANSWERPAPER_STATUS: apStatus.ANSWERPAPER_STATUS
        }
    }

    return {
        status: 50,
        msg: "服务器出行异常"
    }
}

/**
 * 我的答卷
 * @param exam_id
 * @param username
 * @return {Promise<void>}
 */
async function myAnswerPaper(exam_id, username) {

}






/**
 * 从试卷中获取考题（未保存于数据库中）
 * @param tp_id
 * @return {Promise<*>}
 */
async function getExamQuestionFromTestPaper(tp_id) {
    let tpdetail = await TestPaper.findOne({
            where: {
                id: tp_id
            },
            attributes: [
                'id',
                'tp_name',
            ],
            include: [{
                    model: Question,
                    attributes: [
                        'id',
                        'title',
                        'type',
                        'analysis',
                        'difficulty',
                        'qt_body',
                        'QBID',
                    ],
                    through: {
                        model: TestQuestion,
                        attributes: []
                    },
                    include: {
                        model: User,
                        attributes: ['username', 'usernickname']
                    },
                }

            ],
            //使问题类型按升序排序
            order: [
                [Question, 'type']
            ],
        })
        //创建考题（未保存于数据库中）
    let tqs = tpdetail.Questions;
    let eqs = []
    for (let i = 0; i < tqs.length; i++) {
        let eq = {
                type: tqs[i].type,
                analysis: tqs[i].analysis,
                difficulty: tqs[i].difficulty,
                qt_body: tqs[i].qt_body,
                question_id: tqs[i].id,
            }
            // let eq = await ExamQuestion.build({
            //     type:tqs[i].type,
            //     analysis:tqs[i]. analysis,
            //     difficulty:tqs[i].difficulty,
            //     qt_body:tqs[i].qt_body,
            //     question_id:tqs[i].id,
            // });

        eqs.push(eq);
    }
    return eqs;
}

/**
 * 从试卷中获取考题,并且覆盖至考卷当中（保存于数据库中）,并返回考题数组
 * @param tp_id
 * @param ep_id
 * @return {Promise<*>}
 */
async function saveExamQuestionFromTestPaper(tp_id, ep_id) {
    let tpdetail = await TestPaper.findOne({
            where: {
                id: tp_id
            },
            attributes: [
                'id',
                'tp_name',
            ],
            include: [{
                    model: Question,
                    attributes: [
                        'id',
                        'title',
                        'type',
                        'analysis',
                        'difficulty',
                        'qt_body',
                        'QBID',
                    ],
                    through: {
                        model: TestQuestion,
                        attributes: []
                    },
                    include: {
                        model: User,
                        attributes: ['username', 'usernickname']
                    },
                }

            ],
            //使问题类型按升序排序
            order: [
                [Question, 'type']
            ],
        })
        //创建考题（未保存于数据库中）
    let tqs = tpdetail.Questions;
    let eqs = [];
    for (let i = 0; i < tqs.length; i++) {
        let eq = {
            title: tqs[i].title,
            type: tqs[i].type,
            analysis: tqs[i].analysis,
            difficulty: tqs[i].difficulty,
            qt_body: tqs[i].qt_body,
            question_id: tqs[i].id,
            exam_paper_id: ep_id
        }
        await
        // let eq = await ExamQuestion.build({
        //     type:tqs[i].type,
        //     analysis:tqs[i]. analysis,
        //     difficulty:tqs[i].difficulty,
        //     qt_body:tqs[i].qt_body,
        //     question_id:tqs[i].id,
        // });
        eqs.push(eq);
    }
    //删除考卷当中的原题目
    await ExamQuestion.destroy({
        where: {
            exam_paper_id: ep_id
        }
    }).catch(e => { console.log(e) });
    //向考卷存入新题目
    let bulkresult = await ExamQuestion.bulkCreate(eqs).catch(e => { console.log(e) });
    return eqs;
}


/**
 *获取考卷
 * @param ep_id
 * @param hasAnswer
 * @param hasAnalysis
 * @return {Promise<void>}
 */
async function getExamPaper(ep_id) {
    let ep = await ExamPaper.findOne({
        //raw:true,
        where: {
            id: ep_id
        },
        include: {
            model: ExamQuestion,
            raw: true
        }
    })
     ep = ep.toJSON();

    //加入选择题选项个数，加入填空题空位个数
    for (let i = 0; i < ep.ExamQuestions.length; i++) {
        let question = ep.ExamQuestions[i];
        if(question.type === 2 || question.type ===3)
            question.answersNum = question.qt_body.answers.length;
    }
    return ep
}

/**
 * 删除考卷中的答案与解析
 * @param examPaper
 * @return {Promise<void>}
 */
function cutAnswerAndAnalysisOfPaper(examPaper) {
    let eqs = examPaper ?.ExamQuestions
    if (!eqs) throw {
        msg: "考卷中没有题目"
    }
    for (let i = 0; i < eqs.length; i++) {
        delete eqs[i].qt_body.answers
        delete eqs[i].analysis
    }
}



/**
 * 返回一个描述考试状态的对象
 * @description 这个对象有2种返回结果，当status==0时，则可对考试状态做出正确判断，
 * 否则说明学生无本场考试资格
 * @param exam_id {Number}
 * @param username {String}
 * @return {Object}
 * {
 *     {Number} status: 若为0则说明该用户有资格参加这场考试
 *     {String} msg: 关于本函数返回值的描述
 *     {String} EXAM_STATUS:考试的状态描述
 * }
 *
 */
async function examinationStatus(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
        status: 11,
        msg: "用户不存在"
    }

    //判断该考试是否是用户的考试,没资格则status不返回0
    let exam = await Examination.findOne({
        where: {
            id: exam_id
        },
        include: {
            model: Organization,
            include: {
                model: User,
                where: {
                    id: user.id
                }
            },
        }
    })
    if (!exam) return {
        status: 12,
        msg: "权限参与此次考试或考试不存在",
    }

    // ! 考试资格检测通过,status返回0
    //初始化返回结果
    let result = {
            status: 0,
            msg: "",
            EXAM_STATUS: "",
            examination: exam,
        }
        //判断考试是否开始
    if (exam.exam_open_time > new Date()) {
        result.msg = "考试未开始"
        result.EXAM_STATUS = 'NOT_START'
    }
    //判断考试是否结束
    else if (exam.exam_close_time < new Date()) {
        result.msg = "考试已结束"
        result.EXAM_STATUS = "FINISHED"
    }
    //考试正在进行
    else {
        result.msg = "考试正在进行"
        result.EXAM_STATUS = "DOING"
    }
    return result;
}

/**
 * 返回一个描述答卷状态的对象
 * @description 这个对象有2种返回结果，当status==0时，则可对答卷状态做出正确判断，
 * 否则说明学生无本场考试资格
 * @param exam_id {Number}
 * @param username {String}
 * @return {Object}
 * {
 *     {Number} status: 若为0则说明该用户有资格参加这场考试
 *     {String} msg: 关于本函数返回值的描述
 *     {String} ANSWERPAPER_STATUS:考试的状态描述
 * }
 */
async function answerPaperStatus(exam_id, username) {
    //基础属性校验
    {
        if (!exam_id && !username) return { status: 23, msg: "请求参数不能为空" }
    }
    //判断用户合法性
    let user = await User.findOne({
        where: {
            username: username
        }
    })
    if (!user) return {
        status: 11,
        msg: "用户不存在"
    }
    let examStatus = await examinationStatus(exam_id, username);
    //判断用户是否有资格进行考试
    if (examStatus.status !== 0) return examStatus;

    //初始化返回结果
    let result = {
        status: 0,
        msg: "",
        ANSWERPAPER_STATUS: "",
        answerPaper: null,
    }
    let exam = examStatus ?.examination;
    //判断考试状态
    let ap = await AnswerPaper.findOne({
        where: {
            user_id: user.id,
            exam_paper_id: exam.exam_paper_id
        }
    })
    if (!ap) {
        result.msg = "未作答"
        result.ANSWERPAPER_STATUS = "NOT_ANSWER"
    } else {
        result.answerPaper = ap;
        //判断用户是否已经交卷
        if (ap ?.end_time) {
            result.msg = "该用户已经交卷"
            result.ANSWERPAPER_STATUS = "SUBMITTED"
        }
        //判断用户是否超时未交卷
        else if (new Date() >
            Math.min((Number(exam.exam_open_time) + Number(exam.limit_time)), exam.exam_close_time)) {
            result.msg = "该用户超时未交卷"
            result.ANSWERPAPER_STATUS = "TIMEOUT"
        }
        //判断用户是否已经开始答题
        else if (ap ?.start_time) {
            result.msg = "用户正在作答"
            result.ANSWERPAPER_STATUS = 'ANSWERING'
        }

    }


    return result;
}

// async function test(){
//
// }
//
// test();



module.exports = {
    addExam,
    examList,
    updateExam,
    deleteExam,
    myExamList,
    examDetail,
    takeExam,
    examPaper,
    saveAnswerPaper,
    handInPaper,
    myAnswerPaper
}